﻿#define _CRT_SECURE_NO_WARNINGS 1
//
//
//#include<stdio.h>
//#define offsetof(type, member) ((size_t) &((type *)0)->member)

#if 0
这个宏的作用是返回结构体中某个成员的偏移量，
其中type是结构体类型，member是结构体中的成员名。
这个宏的实现原理是利用了C语言中结构体成员的内存布局特性，
将一个指向结构体类型的空指针强制类型转换为结构体类型指针，然后取出成员的地址，
最后通过类型转换得到该成员在结构体中的偏移量。
#endif


//#define SWAP_BITS(num) (((num & 0xAAAAAAAA) >> 1) | ((num & 0x55555555) << 1))
//#include <stdio.h>
//#include <stddef.h>
//
//struct Person {
//    char name[20];
//    int age;
//    float height;
//};
//
//int main() {
//    size_t offset_name = offsetof(struct Person, name);
//    size_t offset_age = offsetof(struct Person, age);
//    size_t offset_height = offsetof(struct Person, height);
//
//    printf("Offset of name: %zu\n", offset_name);
//    printf("Offset of age: %zu\n", offset_age);
//    printf("Offset of height: %zu\n", offset_height);
//
//    return 0;
//}

//int main()
//{
//
//	return 0;
//}

//#include <stdio.h>
//#define __DEBUG__
//
//int main()
//{
//    int i = 0;
//    int arr[10] = { 0 };
//    for (i = 0; i < 10; i++)
//    {
//        arr[i] = i;
//#ifdef __DEBUG__
//        printf("%d\n", arr[i]);//为了观察数组是否赋值成功。  
//#endif //__DEBUG__
//    }
//    return 0;
//}

//1.
//#if 常量表达式
////...
//#endif
////常量表达式由预处理器求值。 
//如：
//#define __DEBUG__ 1
//#if __DEBUG__
////..
//#endif
//2.多个分⽀的条件编译
//#if 常量表达式
////...
//#elif 常量表达式
////...
//#else
////...
//#endif
//3.判断是否被定义
//#if defined(symbol)
//#ifdef symbol
//#if !defined(symbol)
//#ifndef symbol
//4.嵌套指令
//#if defined(OS_UNIX)
//#ifdef OPTION1
//unix_version_option1();
//#endif
//#ifdef OPTION2
//unix_version_option2();
//#endif
//#elif defined(OS_MSDOS)
//#ifdef OPTION2
//msdos_version_option2();
//#endif
//#endif
//
//#if defined(OS_UNIX)
//#ifdef OPTION1
//unix_version_option1();
//#endif
//#ifdef OPTION2
//unix_version_option2();
//#endif
//#elif defined(OS_MSDOS)
//#ifdef OPTION2
//msdos_version_option2();
//#endif
//#endif

//写一个宏，计算结构体中某变量相对于首地址的偏移，并给出说明
//
//考察：offsetof宏的实现

//#include<stdio.h>
//#define offset(structType, MemberName) ((size_t)&((structType*)0)->MemberName) 
//Struct是结构体类型名,MenberName是成员名.
//1、先将0转换为一个结构体类型的指针，
// 相当于某个结构体的首地址是0。
// 此时，每一个成员的偏移量就成了相对0的偏移量，
// 这样就不需要减去首地址了。
//
//2、对该指针用->访问其成员，并取出地址，
// 由于结构体起始地址为0，此时成员偏移量直接相当于对0的偏移量，
// 所以得到的值直接就是对首地址的偏移量。
//
//3、取出该成员的地址，强转成size_t并打印，就求出了这个偏移量。
//struct stu
//{
//	char name[10];
//	int age;
//	char sex[10];
//};
//
//int main()
//{
//	size_t ret = 0;
//	ret = offset(struct stu, age);
//	printf("%d\n", ret);
//	return 0;
//}
//
////写一个宏，可以将一个整数的二进制位的奇数位和偶数位交换。
//
//#define SWAP_BITS(num) (((num & 0xAAAAAAAA) >> 1) | ((num & 0x55555555) << 1))

//交换奇偶位，需要先分别拿出奇偶位。
//既然是宏，分别拿出用循环不是很现实，
//那就用& 这些位的方式来做。奇数位拿出，
//那就是要& 上010101010101……，偶数位拿出，
//就是要& 上101010101010……，对应十六进制分别是555……和aaa……，
//一般我们默认是32位整数，4位对应一位16进制就是8个5，8个a。
//通过 & 0x55555555的方式拿出奇数位和 & 0xaaaaaaa的方式拿出偶数位。
//奇数位左移一位就到了偶数位上，偶数位右移一位就到了奇数位上，
//最后两个数字或起来，就完成了交换。
//
//这个宏只能完成32位以内的整形，要想完成64位的，那就将5和a的数量翻倍即可。